package com.leon.datalink.core.persistence;

import com.leon.datalink.core.evn.EnvUtil;
import org.junit.Before;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

import static org.junit.Assert.*;

/**
 * 持久化配置管理器测试
 * 
 * @author leon
 */
public class PersistenceConfigManagerTest {
    
    private PersistenceConfigManager configManager;
    
    @Before
    public void setUp() {
        // 重置环境变量
        System.clearProperty("datalink.persistence.enabled");
        System.clearProperty("datalink.persistence.strategy");
        System.clearProperty("datalink.persistence.critical.actors");
        
        configManager = PersistenceConfigManager.getInstance();
    }
    
    @Test
    public void testGlobalPersistenceDisabled() {
        // 设置全局持久化为禁用
        System.setProperty("datalink.persistence.enabled", "false");
        configManager.reloadConfiguration();
        
        Map<String, Object> properties = new HashMap<>();
        
        // 即使是关键Actor，也不应该持久化
        assertFalse(configManager.shouldPersist("test-rule", "RuleActor", properties));
        assertFalse(configManager.shouldPersist("test-schedule", "ScheduleNodeActor", properties));
    }
    
    @Test
    public void testSelectiveStrategy() {
        // 启用持久化，使用选择性策略
        System.setProperty("datalink.persistence.enabled", "true");
        System.setProperty("datalink.persistence.strategy", "selective");
        System.setProperty("datalink.persistence.critical.actors", "RuleActor,ScheduleNodeActor");
        configManager.reloadConfiguration();
        
        Map<String, Object> properties = new HashMap<>();
        
        // 关键Actor应该持久化
        assertTrue(configManager.shouldPersist("test-rule", "RuleActor", properties));
        assertTrue(configManager.shouldPersist("test-schedule", "ScheduleNodeActor", properties));
        
        // 非关键Actor不应该持久化
        assertFalse(configManager.shouldPersist("test-filter", "FilterNodeActor", properties));
    }
    
    @Test
    public void testAllStrategy() {
        // 启用持久化，使用全部策略
        System.setProperty("datalink.persistence.enabled", "true");
        System.setProperty("datalink.persistence.strategy", "all");
        configManager.reloadConfiguration();
        
        Map<String, Object> properties = new HashMap<>();
        
        // 所有Actor都应该持久化
        assertTrue(configManager.shouldPersist("test-rule", "RuleActor", properties));
        assertTrue(configManager.shouldPersist("test-filter", "FilterNodeActor", properties));
        assertTrue(configManager.shouldPersist("test-any", "AnyActor", properties));
    }
    
    @Test
    public void testNoneStrategy() {
        // 启用持久化，但使用none策略
        System.setProperty("datalink.persistence.enabled", "true");
        System.setProperty("datalink.persistence.strategy", "none");
        configManager.reloadConfiguration();
        
        Map<String, Object> properties = new HashMap<>();
        
        // 所有Actor都不应该持久化
        assertFalse(configManager.shouldPersist("test-rule", "RuleActor", properties));
        assertFalse(configManager.shouldPersist("test-filter", "FilterNodeActor", properties));
    }
    
    @Test
    public void testInstanceLevelConfiguration() {
        // 启用持久化，使用选择性策略
        System.setProperty("datalink.persistence.enabled", "true");
        System.setProperty("datalink.persistence.strategy", "selective");
        configManager.reloadConfiguration();
        
        Map<String, Object> properties = new HashMap<>();
        
        // 设置实例级配置
        configManager.setInstancePersistence("special-node", true);
        configManager.setInstancePersistence("temp-node", false);
        
        // 实例级配置应该优先于类型配置
        assertTrue(configManager.shouldPersist("special-node", "FilterNodeActor", properties));
        assertFalse(configManager.shouldPersist("temp-node", "RuleActor", properties));
    }
    
    @Test
    public void testActorTypeConfiguration() {
        // 启用持久化，使用选择性策略
        System.setProperty("datalink.persistence.enabled", "true");
        System.setProperty("datalink.persistence.strategy", "selective");
        configManager.reloadConfiguration();
        
        Map<String, Object> properties = new HashMap<>();
        
        // 设置Actor类型配置
        configManager.setActorTypePersistence("CustomActor", true);
        
        // 自定义Actor类型应该持久化
        assertTrue(configManager.shouldPersist("test-custom", "CustomActor", properties));
    }
    
    @Test
    public void testBusinessRules() {
        // 启用持久化，使用选择性策略
        System.setProperty("datalink.persistence.enabled", "true");
        System.setProperty("datalink.persistence.strategy", "selective");
        System.setProperty("datalink.persistence.rules.stateful-nodes", "true");
        System.setProperty("datalink.persistence.rules.critical-nodes", "true");
        configManager.reloadConfiguration();
        
        // 测试有状态节点
        Map<String, Object> statefulProperties = new HashMap<>();
        statefulProperties.put("stateful", true);
        assertTrue(configManager.shouldPersist("test-stateful", "UnknownActor", statefulProperties));
        
        // 测试关键节点
        Map<String, Object> criticalProperties = new HashMap<>();
        criticalProperties.put("critical", true);
        assertTrue(configManager.shouldPersist("test-critical", "UnknownActor", criticalProperties));
        
        // 测试普通节点
        Map<String, Object> normalProperties = new HashMap<>();
        assertFalse(configManager.shouldPersist("test-normal", "UnknownActor", normalProperties));
    }
    
    @Test
    public void testConfigurationPriority() {
        // 启用持久化，使用选择性策略
        System.setProperty("datalink.persistence.enabled", "true");
        System.setProperty("datalink.persistence.strategy", "selective");
        configManager.reloadConfiguration();
        
        Map<String, Object> properties = new HashMap<>();
        properties.put("stateful", true); // 业务规则说应该持久化
        
        // 设置Actor类型配置为不持久化
        configManager.setActorTypePersistence("TestActor", false);
        
        // 设置实例级配置为持久化
        configManager.setInstancePersistence("test-instance", true);
        
        // 实例级配置应该优先于类型配置和业务规则
        assertTrue(configManager.shouldPersist("test-instance", "TestActor", properties));
        
        // 类型配置应该优先于业务规则
        assertFalse(configManager.shouldPersist("other-instance", "TestActor", properties));
    }
}
